package com.javacv.plus.examples.service;

import com.javacv.plus.extensions.video.VideoProcessor;
import com.javacv.plus.extensions.video.VideoResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

@Slf4j
@Service
public class VideoService {

    private final Path tempDir;

    public VideoService() {
        this.tempDir = Paths.get(System.getProperty("java.io.tmpdir"), "javacv-plus");
        try {
            Files.createDirectories(tempDir);
        } catch (IOException e) {
            log.error("Failed to create temp directory", e);
        }
    }

    public String convertVideo(MultipartFile file, String format) {
        try {
            File inputFile = saveTempFile(file);
            File outputFile = new File(tempDir.toFile(), UUID.randomUUID() + "." + format);
            
            VideoResult result = VideoProcessor.of(inputFile.getAbsolutePath())
                .convertFormat(format)
                .save(outputFile.getAbsolutePath());
            
            return result.getOutputPath();
        } catch (Exception e) {
            log.error("Failed to convert video", e);
            throw new RuntimeException("Video conversion failed", e);
        }
    }

    public String compressVideo(MultipartFile file, double quality) {
        try {
            File inputFile = saveTempFile(file);
            File outputFile = new File(tempDir.toFile(), UUID.randomUUID() + ".mp4");
            
            VideoResult result = VideoProcessor.of(inputFile.getAbsolutePath())
                .compress(String.valueOf(quality))
                .save(outputFile.getAbsolutePath());
            
            return result.getOutputPath();
        } catch (Exception e) {
            log.error("Failed to compress video", e);
            throw new RuntimeException("Video compression failed", e);
        }
    }

    public String extractFrames(MultipartFile file, int interval) {
        try {
            File inputFile = saveTempFile(file);
            File outputDir = new File(tempDir.toFile(), UUID.randomUUID().toString());
            outputDir.mkdirs();
            
            VideoResult result = VideoProcessor.of(inputFile.getAbsolutePath())
                .extractFrames(interval)
                .save(outputDir.getAbsolutePath());
            
            return result.getOutputPath();
        } catch (Exception e) {
            log.error("Failed to extract frames", e);
            throw new RuntimeException("Frame extraction failed", e);
        }
    }

    public String mergeVideos(MultipartFile[] files) {
        try {
            File[] inputFiles = new File[files.length];
            for (int i = 0; i < files.length; i++) {
                inputFiles[i] = saveTempFile(files[i]);
            }
            File outputFile = new File(tempDir.toFile(), UUID.randomUUID() + ".mp4");
            
            // 合并视频需要特殊处理，这里暂时返回错误
            throw new UnsupportedOperationException("Video merging is not supported yet");
        } catch (Exception e) {
            log.error("Failed to merge videos", e);
            throw new RuntimeException("Video merge failed", e);
        }
    }

    public String addWatermark(MultipartFile file, MultipartFile watermark, String position) {
        try {
            File inputFile = saveTempFile(file);
            File watermarkFile = saveTempFile(watermark);
            File outputFile = new File(tempDir.toFile(), UUID.randomUUID() + ".mp4");
            
            // 解析位置字符串为 x, y 坐标
            String[] pos = position.split(",");
            int x = Integer.parseInt(pos[0].trim());
            int y = Integer.parseInt(pos[1].trim());
            
            VideoResult result = VideoProcessor.of(inputFile.getAbsolutePath())
                .addWatermark(watermarkFile.getAbsolutePath(), x, y)
                .save(outputFile.getAbsolutePath());
            
            return result.getOutputPath();
        } catch (Exception e) {
            log.error("Failed to add watermark", e);
            throw new RuntimeException("Watermark addition failed", e);
        }
    }

    public String cutVideo(MultipartFile file, int startTime, int duration) {
        try {
            File inputFile = saveTempFile(file);
            File outputFile = new File(tempDir.toFile(), UUID.randomUUID() + ".mp4");
            
            VideoResult result = VideoProcessor.of(inputFile.getAbsolutePath())
                .trim(startTime, duration)
                .save(outputFile.getAbsolutePath());
            
            return result.getOutputPath();
        } catch (Exception e) {
            log.error("Failed to cut video", e);
            throw new RuntimeException("Video cut failed", e);
        }
    }

    public String rotateVideo(MultipartFile file, int angle) {
        try {
            File inputFile = saveTempFile(file);
            File outputFile = new File(tempDir.toFile(), UUID.randomUUID() + ".mp4");
            
            // 旋转视频需要特殊处理，这里暂时返回错误
            throw new UnsupportedOperationException("Video rotation is not supported yet");
        } catch (Exception e) {
            log.error("Failed to rotate video", e);
            throw new RuntimeException("Video rotation failed", e);
        }
    }

    public String resizeVideo(MultipartFile file, int width, int height) {
        try {
            File inputFile = saveTempFile(file);
            File outputFile = new File(tempDir.toFile(), UUID.randomUUID() + ".mp4");
            
            VideoResult result = VideoProcessor.of(inputFile.getAbsolutePath())
                .resize(width, height)
                .save(outputFile.getAbsolutePath());
            
            return result.getOutputPath();
        } catch (Exception e) {
            log.error("Failed to resize video", e);
            throw new RuntimeException("Video resize failed", e);
        }
    }

    private File saveTempFile(MultipartFile file) throws IOException {
        File tempFile = new File(tempDir.toFile(), UUID.randomUUID() + getFileExtension(file.getOriginalFilename()));
        file.transferTo(tempFile);
        return tempFile;
    }

    private String getFileExtension(String filename) {
        return filename != null && filename.contains(".") ? filename.substring(filename.lastIndexOf(".")) : "";
    }
} 